namespace Org.Loon.Framework.Xna.Game.Action.Collision
{
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;
    using Org.Loon.Framework.Xna.Game.Core.Geom;
    using Org.Loon.Framework.Xna.Game.Core.Graphics;
    using Org.Loon.Framework.Xna.Game.Utils;
    using Org.Loon.Framework.Xna.Game.Core.Input;

    public class CollisionManager
    {

        private List<CollisionEvent> actionListener;

        private CollisionListener listener;

        private Screen screen;

        public CollisionManager(Screen s, CollisionListener l)
        {
            this.screen = s;
            this.listener = l;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public void AddCollisionListener(CollisionEvent e)
        {
            if (this.actionListener == null)
            {
                this.actionListener = new List<CollisionEvent>();
            }
            CollectionUtils.Add(this.actionListener, e);
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public void RemoveCollisionListener(CollisionEvent e)
        {
            if ((this.actionListener != null))
            {
                CollectionUtils.Remove(this.actionListener, e);
            }
        }

        private void ProcessClickEvent(bool on)
        {
            if (on)
            {
                if (!Touch.IsDown())
                {
                    return;
                }
            }
            else
            {
                if (!Touch.IsUp())
                {
                    return;
                }
            }
            List<CollisionEvent> actionEventList = CopyAction();
            if (actionEventList == null)
            {
                return;
            }
            foreach (CollisionEvent actionEvent in actionEventList)
            {
                Collidable collidable = actionEvent.GetCollidable();
                if (collidable == null)
                {
                    continue;
                }
                Shape shape = collidable.GetShape();
                if (shape != null
                        && shape.Contains(screen.GetTouchX(), screen.GetTouchY()))
                {
                    listener.OnClick(actionEvent);
                }
            }
        }

        public void ProcessOnClickEvent()
        {
            ProcessClickEvent(true);
        }

        public void ProcessUpClickEvent()
        {
            ProcessClickEvent(false);
        }

        public void ProcessCollidesWithEvent(Collidable o)
        {
            if (o == null)
            {
                return;
            }
            List<CollisionEvent> actionEventList = CopyAction();
            if (actionEventList == null)
            {
                return;
            }
            foreach (CollisionEvent actionEvent in actionEventList)
            {
                Collidable collidable = actionEvent.GetCollidable();
                if (collidable == null)
                {
                    continue;
                }
                Shape shape = collidable.GetShape();
                if (shape != null && shape.Intersects(o.GetShape()))
                {
                    listener.OnCollidesWith(actionEvent);
                }
            }
        }

        private List<CollisionEvent> CopyAction()
        {
            List<CollisionEvent> actionEventList;
            lock (this)
            {
                if (this.actionListener == null)
                {
                    return null;
                }
                actionEventList = new List<CollisionEvent>(this.actionListener);
            }
            return actionEventList;
        }
    }
}
